/*
 * 
 */
package org.spring.config.server.config;

import java.io.File;
import java.util.List;

import org.spring.config.server.controller.EnvironmentController;
import org.spring.config.server.page.table.PageTableArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.cloud.config.server.config.ConfigServerProperties;
import org.springframework.cloud.config.server.encryption.EnvironmentEncryptor;
import org.springframework.cloud.config.server.environment.EnvironmentEncryptorEnvironmentRepository;
import org.springframework.cloud.config.server.environment.EnvironmentRepository;
import org.springframework.cloud.config.server.resource.ResourceController;
import org.springframework.cloud.config.server.resource.ResourceRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.util.ResourceUtils;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * 
 * ClassName: ConfigServerMvcConfiguration <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON(可选). <br/>
 * date: 2019年10月10日 上午11:38:39 <br/>
 *
 * @author dengqian
 * @version
 * @since JDK 1.8
 */
@Configuration
@ConditionalOnWebApplication
public class ConfigServerMvcConfiguration extends WebMvcConfigurerAdapter {

    @Autowired(required = false)
    private EnvironmentEncryptor environmentEncryptor;
//    Priority//
    @Autowired(required = false)
    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.mediaType("properties", MediaType.valueOf("text/plain"));
        configurer.mediaType("yml", MediaType.valueOf("text/yaml"));
        configurer.mediaType("yaml", MediaType.valueOf("text/yaml"));
    }

    @Bean
    public EnvironmentController environmentController(EnvironmentRepository envRepository,
        ConfigServerProperties server) {
        EnvironmentController controller =
            new EnvironmentController(encrypted(envRepository, server), this.objectMapper);
        
        
        controller.setStripDocumentFromYaml(server.isStripDocumentFromYaml());
        return controller;
    }

    @Bean
    @ConditionalOnBean(ResourceRepository.class)
    public ResourceController resourceController(ResourceRepository repository, EnvironmentRepository envRepository,
        ConfigServerProperties server) {
        ResourceController controller = new ResourceController(repository, encrypted(envRepository, server));
        return controller;
    }

    private EnvironmentRepository encrypted(EnvironmentRepository envRepository, ConfigServerProperties server) {
        EnvironmentEncryptorEnvironmentRepository encrypted =
            new EnvironmentEncryptorEnvironmentRepository(envRepository, this.environmentEncryptor);
        encrypted.setOverrides(server.getOverrides());
        return encrypted;
    }
    
    @Bean
    public PageTableArgumentResolver tableHandlerMethodArgumentResolver() {
        return new PageTableArgumentResolver();
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(tableHandlerMethodArgumentResolver());
    }
    
    @Value("${files.path}")
    private String filesPath;
    
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        System.out.println(filesPath);
        registry.addResourceHandler("/static/**")
                .addResourceLocations(ResourceUtils.FILE_URL_PREFIX + filesPath + File.separator);
    }
    
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true); // 允许cookies跨域
        config.addAllowedOrigin("*");// 允许向该服务器提交请求的URI，*表示全部允许。。这里尽量限制来源域，比如http://xxxx:8080
                                        // ,以降低安全风险。。
        config.addAllowedHeader("*");// 允许访问的头信息,*表示全部
        config.setMaxAge(18000L);// 预检请求的缓存时间（秒），即在这个时间段里，对于相同的跨域请求不会再预检了
        config.addAllowedMethod("*");// 允许提交请求的方法，*表示全部允许，也可以单独设置GET、PUT等
        /*
         * config.addAllowedMethod("HEAD"); config.addAllowedMethod("GET");//
         * 允许Get的请求方法 config.addAllowedMethod("PUT");
         * config.addAllowedMethod("POST"); config.addAllowedMethod("DELETE");
         * config.addAllowedMethod("PATCH");
         */
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}
